package com.lengyu.vxminiprogram.log;


import com.alibaba.fastjson.JSONObject;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 编写一个切面，用于打印每个执行方法日志
 * @author liuyu 2019.11.27
 *
 * */
@Aspect
@Component
public class LogAspect {

    private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);

    @Pointcut(value = "execution(* com.lengyu.vxminiprogram.controller.*.*(..)) || execution(* com.lengyu.vxminiprogram.*.controller.*.*(..)) || execution(* com.lengyu.vxminiprogram.*.*.controller.*.*(..))")
    public void pc(){}

    /**
     * 方法进入的时候开始执行，打印方法名和参数
     * */
    @Before(value="pc()")
    public void before(JoinPoint joinPoint){
        String name = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        List<String> list = new ArrayList<>();
        if(args != null && args.length > 0){
            for (Object o : args) {
                // 如果参数为request或者response或者文件时，略过
                if(!(o instanceof HttpServletRequest) && !(o instanceof HttpServletResponse) && !(o instanceof MultipartFile)&& !(o instanceof MultipartFile[])){
                    list.add(JSONObject.toJSONString(o));
                }
            }
        }
        logger.info("###" + joinPoint.getSignature().getDeclaringTypeName() + "_ " + name + "###方法开始执行...，参数为：" + list.toString());
    }

    @Around(value="pc()")
    public Object handleControllerMethod(ProceedingJoinPoint pjp) throws Throwable {
        long start = new Date().getTime();
        Object object = pjp.proceed();
        String costTime= String.valueOf(new Date().getTime() - start);
        logger.info(pjp.getSignature().getDeclaringTypeName() + "_ " + pjp.getSignature().getName()  + " 方法执行时间为 :" + costTime + "ms");
        return object;
    }

    /**
     * 方法正常执行后返回结果，如果异常，则不走
     * */
    @AfterReturning(value = "pc()" , returning = "result")
    public void afterReturning(JoinPoint jp, Object result){
        String name = jp.getSignature().getName();
        logger.info(name+"方法返回值为："+ JSONObject.toJSONString(result));
    }
}
